package player

import (
	"GameServer/Common/data"
	"GameServer/Common/utils"
	"GameServer/Game/errors"
	"GameServer/Game/lib"
	"GameServer/Game/m"
	"GameServer/Game/sp"
	"fmt"

	log "github.com/sirupsen/logrus"
)

// 8680 Boss老虎机 获取基本信息
func (p *Player) BossSlotInfoRequest(req *sp.BossSlotInfoRequest) (res *sp.BossSlotInfoResponse) {
	us := p.User
	// 加载Boss，获取配置表信息
	wActconfig, actConfig, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		log.WithFields(log.Fields{
			"method": "BossSlotInfoRequest",
		}).Error("没找找到活动排名配置表")
		return
	}
	// 活动序号
	activID := int64(actConfig.ActivId)
	// 活动结束时间
	actEndTime, _ := utils.LayoutToTime(actConfig.EndTime)
	// 战斗结束时间
	combatEndTime := actEndTime.Unix() - 86400 // 提前一天，战斗结束

	group, ok := us.GetMCGroup()
	if !ok {
		err = errors.NewErrcode(data.Errcode.ServerErr, "查找分组失败")
		res = &sp.BossSlotInfoResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	gamer, ok := us.GetMCGamer()
	if !ok {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "查找玩家失败")
		res = &sp.BossSlotInfoResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	// 查找当前正在被攻击的怪
	var monsterID int64 = 0  // 当前怪
	var fmonsterID int64 = 0 // 最后怪
	for _, item := range wActconfig.BossLst {
		fmonsterID = int64(item)
		boss, _ := group.MBoss[fmonsterID]
		if boss.Hp > 0 {
			monsterID = fmonsterID
			break
		}
	}
	if monsterID == 0 {
		fmt.Println("boss死完，或者没有该Boss")
		monsterID = fmonsterID
	}
	// 获取怪的信息
	moster, err := lib.GetCardMonster(monsterID)
	if err != nil {
		fmt.Println("获取卡片怪兽失败", err)
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "获取卡片怪兽失败")
		res = &sp.BossSlotInfoResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 当前怪-真实血量
	moster.Hp = group.MBoss[monsterID].Hp

	// 获取玩家多人战斗M层数据，会检测ActvId,和旧M中的(CombatEndTime+86400)<time.Now.Unix()
	card := us.GetBSGameByActId(activID, combatEndTime)
	if card == nil {
		fmt.Println("没有该多人战斗游戏")
		err = errors.NewErrcode(data.Errcode.NotFound, "没有该多人战斗游戏")
		res = &sp.BossSlotInfoResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	bossLst := make([]*sp.MulCombatBossState, 0)
	for _, item := range wActconfig.BossLst {
		bossTid := int64(item)
		var isGain int64 = 0
		if card.IsGainBonus_BossDefeat(bossTid) {
			isGain = 1
		}
		boss, _ := group.MBoss[int64(item)]
		var isAlive int64 = 0
		if boss.Hp <= 0 {
			isAlive = 1
		}
		// 伤害小于1万，不能领取该奖励。
		if gamer.MEachBossHurt[bossTid] < data.BossHurtReward {
			isGain = 1
		}

		bossLst = append(bossLst, &sp.MulCombatBossState{
			MonsterID: bossTid,
			IsAlive:   isAlive, //0-存活 1-击败
			IsGain:    isGain,  //0-未领取奖励 1-已领取奖励
		})
	}

	// 获取累计伤害奖励列表
	bosDmgActs, err := lib.GetBossDmgAccuBonus(int64(wActconfig.DmgAccuBonusId))
	if err != nil {
		fmt.Println("获取累计伤害配表失败", err)
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "获取累计伤害配表失败")
		res = &sp.BossSlotInfoResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	dmgBonusState := make([]*sp.MulCombatDmgAccuBonusState, 0)
	for _, item := range bosDmgActs {
		bonusId := int64(item.Id)
		var isGain int64 = 0
		if card.IsGainBonus_DmgAccu(bonusId) {
			isGain = 1
		}
		dmgBonusState = append(dmgBonusState, &sp.MulCombatDmgAccuBonusState{
			BonusId: bonusId, // 累计奖励Id
			IsGain:  isGain,  // 是否领取奖励
		})
	}

	res = &sp.BossSlotInfoResponse{
		ActivID:         int64(actConfig.ActivId),        // 活动ID
		CombatEndTime:   combatEndTime,                   // 战斗结束时间
		MonsterID:       monsterID,                       // 多人战斗中的BOSS的ID
		BossLst:         bossLst,                         // BOSS列表信息
		Monster:         lib.FormatCardMonsterSp(moster), // 怪物信息
		DmgBonusState:   dmgBonusState,                   // 累计伤害奖励列表信息
		DmgAccu:         gamer.Hurt,                      // 玩家累计伤害
		EachBossDmgAccu: lib.FormatBaseKVLst(gamer.MEachBossHurt),
	}
	return
}

// 8681 Boss老虎机 进入战斗
func (p *Player) BossSlotIntoFightRequest(req *sp.BossSlotIntoFightRequest) (res *sp.BossSlotIntoFightResponse) {
	us := p.User
	//todo 首次、再次进入战斗，在buff上的留存区别，不是直接new
	//todo 进入时，判断endTime,数据层采用懒更新。需要识别这个数据是不是过期数据，是的话要new一个
	cardGame, err := lib.NewCardGame_BSGame(us, req.ActivID, req.MonsterID)
	if err != nil {
		res = &sp.BossSlotIntoFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		log.WithFields(log.Fields{
			"method": "MulCombatBossDefeatRewardRequest",
		}).Error("没找找到活动排名配置表")
		res = &sp.BossSlotIntoFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	group, ok := us.GetMCGroup()
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "查找分组失败")
		res = &sp.BossSlotIntoFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	gamer, ok := us.GetMCGamer()
	if !ok {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "查找玩家失败")
		res = &sp.BossSlotIntoFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	card := us.GetBSGame()
	if card == nil {
		err = errors.NewErrcode(data.Errcode.NotFound, "没有该多人战斗游戏")
		res = &sp.BossSlotIntoFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	bossLst := make([]*sp.MulCombatBossState, 0)
	for _, item := range wActconfig.BossLst {
		bossTid := int64(item)
		var isGain int64 = 0
		if card.IsGainBonus_BossDefeat(bossTid) {
			isGain = 1
		}
		boss, _ := group.MBoss[int64(item)]
		var isAlive int64 = 0
		if boss.Hp <= 0 {
			isAlive = 1
		}
		// 伤害小于1万，不能领取该奖励。
		if gamer.MEachBossHurt[bossTid] < data.BossHurtReward {
			isGain = 1
		}

		bossLst = append(bossLst, &sp.MulCombatBossState{
			MonsterID: bossTid,
			IsAlive:   isAlive, //0-存活 1-击败
			IsGain:    isGain,  //0-未领取奖励 1-已领取奖励
		})
	}

	res = &sp.BossSlotIntoFightResponse{
		CombatEndTime: cardGame.EndTime,
		ActivID:       cardGame.ActivId,
		BossLst:       bossLst,
		Monster:       lib.FormatCardMonsterSp(cardGame.Monster),
		CardBuffs:     lib.FormatCardBuffSps(cardGame.CardBuffs),
		Round:         cardGame.Round,
		PlayerShield:  cardGame.PlayerShield,
		Hp:            cardGame.HP,
		Energy:        cardGame.Energy,
		DmgBonus:      cardGame.DmgBonus,
	}
	return
}

// 8682 Boss老虎机 战斗
func (p *Player) BossSlotFightRequest(req *sp.BossSlotFightRequest) (res *sp.BossSlotFightResponse) {
	us := p.User

	cardGame := us.GetBSGame()
	defer cardGame.Update(cardGame)
	cardGame.Spin = req.Spin

	//玩家消耗的金币=老虎机倍率*下注
	uProp, err := lib.Cost("BossSlotFightRequest", us, []m.BaseKV{{Key: data.GlobalEnum.Gold, Val: req.Spin * cardGame.Wager}})
	if err != nil {
		res = &sp.BossSlotFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})

	gmKey := int64(0)
	if BossSlotKey, ok := p.GetData("BossSlotKey"); ok {
		gmKey = BossSlotKey.(int64)
	}
	// 摇转Boss老虎机
	slotKey, slotCard, err := lib.BossSlotRotating(us, req.Spin, gmKey)
	if err != nil {
		res = &sp.BossSlotFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	playerHattrs := make([]*m.HurtAttr, 0)
	// 有效卡片
	if slotCard > 0 {
		// 发起攻击
		playerHattrs, err = lib.UseCard_BSGame(us, cardGame, slotCard, p.Send)
		if err != nil {
			res = &sp.BossSlotFightResponse{
				Errcode: errors.ErrCode(err),
			}
			return
		}

		if cardGame.Status > 0 {
			res = &sp.BossSlotFightResponse{
				Status:        cardGame.Status,
				Round:         cardGame.Round,
				CardId:        slotCard,
				PlayerCardAtt: lib.FormatHurtAttrSps(playerHattrs),
				CardBuffs:     lib.FormatCardBuffSps(cardGame.CardBuffs),
				Monster:       lib.FormatCardMonsterSp(cardGame.Monster),
				DmgAccu:       cardGame.DmgAccu,
				PlayerShield:  cardGame.PlayerShield,
				SlotKey:       slotKey,
				Hp:            cardGame.HP,
				Energy:        cardGame.Energy,
				DmgBonus:      cardGame.DmgBonus,
			}
			return
		}
	}

	// 怪攻击
	monsterHattrs, err := lib.RoundEnd_BSGame(cardGame)
	if err != nil {
		res = &sp.BossSlotFightResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	res = &sp.BossSlotFightResponse{
		Status:         cardGame.Status,
		Round:          cardGame.Round,
		CardId:         slotCard,
		PlayerCardAtt:  lib.FormatHurtAttrSps(playerHattrs),
		CardBuffs:      lib.FormatCardBuffSps(cardGame.CardBuffs),
		MonsterCardAtt: lib.FormatHurtAttrSps(monsterHattrs),
		Monster:        lib.FormatCardMonsterSp(cardGame.Monster),
		DmgAccu:        cardGame.DmgAccu,
		PlayerShield:   cardGame.PlayerShield,
		SlotKey:        slotKey,
		Hp:             cardGame.HP,
		Energy:         cardGame.Energy,
		DmgBonus:       cardGame.DmgBonus,
		ShopState:      lib.BossSlotCheckShop(cardGame), // 检测神秘商店是否开启
	}
	return
}

// 8683 Boss老虎机 领取击退BOSS奖励
func (p *Player) BossSlotBossRewardRequest(req *sp.BossSlotBossRewardRequest) (res *sp.BossSlotBossRewardResponse) {
	us := p.User

	card := us.GetBSGame()
	if card == nil {
		err := errors.NewErrcode(data.Errcode.ServerErr, "没有该玩家战斗信息")
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// boss奖励是否领取。
	if card.IsGainBonus_BossDefeat(req.MonsterID) {
		fmt.Println("该Boss奖励，已经领取")
		err := errors.NewErrcode(data.Errcode.ServerErr, "该Boss奖励，已经领取")
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	gamer, ok := us.GetMCGamer()
	if !ok {
		err := errors.NewErrcode(data.Errcode.UserNotFound, "查找玩家失败")
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	// 领取boss奖励，修改状态
	card.SetGainBonus_BossDefeat(req.MonsterID)

	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		log.WithFields(log.Fields{
			"method": "BossSlotBossRewardRequest",
		}).Error("没找找到活动排名配置表")
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	fIdx := -1
	for idx, item := range wActconfig.BossLst {
		if req.MonsterID == int64(item) {
			fIdx = idx
			break
		}
	}
	if fIdx < 0 {
		// 没有该Boss
		err = errors.NewErrcode(data.Errcode.NotFound, "没有该Boss")
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 给玩家添加道具
	uProp, resGoods, boxResList, err := lib.GiveGoodsByKv("MulCombatBossDefeatRewardRequest", us, m.BaseKV{Key: int64(wActconfig.BossRewards[fIdx]), Val: 1}, p.Send)
	if err != nil {
		res = &sp.BossSlotBossRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	group, _ := us.GetMCGroup()
	bossLst := make([]*sp.MulCombatBossState, 0)

	for _, item := range group.MBoss {
		var isGain int64 = 0
		if card.IsGainBonus_BossDefeat(item.Tid) { // 该Boss奖励，是否领取。
			isGain = 1
		}
		var isAlive int64 = 0
		if item.Hp <= 0 { // Boss血量小于等于0，死了。
			isAlive = 1
		}
		// 伤害小于1万，不能领取该奖励。
		if gamer.MEachBossHurt[item.Tid] < data.BossHurtReward {
			isGain = 1
		}

		bossLst = append(bossLst, &sp.MulCombatBossState{
			MonsterID: item.Tid,
			IsAlive:   isAlive, //0-存活 1-击败
			IsGain:    isGain,  //0-未领取奖励 1-已领取奖励
		})
	}

	res = &sp.BossSlotBossRewardResponse{
		MonsterID: req.MonsterID,
		BossLst:   bossLst, // BOSS列表信息
		Res:       lib.FormatGoodsInfoSps(resGoods),
		BoxRes:    lib.FormatBoxResSps(boxResList),
	}
	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	return
}

// 8684 Boss老虎机 领取伤害累计奖励
func (p *Player) BossSlotCumulRewardRequest(req *sp.BossSlotCumulRewardRequest) (res *sp.BossSlotCumulRewardResponse) {
	us := p.User
	// 累计伤害id
	fmt.Println(req.BonusId)
	card := us.GetBSGame()
	if card == nil {
		err := errors.NewErrcode(data.Errcode.NotFound, "没有该多人战斗游戏")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	if card.IsGainBonus_DmgAccu(req.BonusId) {
		err := errors.NewErrcode(data.Errcode.ServerErr, "已经领取该奖励")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		log.WithFields(log.Fields{
			"method": "BossSlotCumulRewardRequest",
		}).Error("没找找到活动排名配置表")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 获取累计伤害奖励列表
	bosDmgActs, err := lib.GetBossDmgAccuBonus(int64(wActconfig.DmgAccuBonusId))
	if err != nil {
		err := errors.NewErrcode(data.Errcode.NotFound, "获取累计伤害配表失败")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	bosDmgAct, ok := bosDmgActs[req.BonusId]
	if !ok {
		err := errors.NewErrcode(data.Errcode.NotFound, "没有该伤害值")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	gamer, _ := us.GetMCGamer()
	// 玩家累计伤害 < 奖励伤害 不可领取奖励
	if gamer.Hurt < int64(bosDmgAct.Dmg) {
		err := errors.NewErrcode(data.Errcode.NotFound, "没有达到该伤害")
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	// 领取奖励
	uProp, resGoods, boxResList, err := lib.GiveGoodsByKv("BossSlotCumulRewardRequest", p.User, m.BaseKV{Key: int64(bosDmgAct.ItemId), Val: int64(bosDmgAct.Count)}, p.Send)
	if err != nil {
		res = &sp.BossSlotCumulRewardResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	// 修改领取奖励状态
	card.SetGainBonus_DmgAccu(req.BonusId)

	dmgBonusState := make([]*sp.MulCombatDmgAccuBonusState, 0)
	for _, item := range bosDmgActs {
		bonusId := int64(item.Id)
		var isGain int64 = 0
		if card.IsGainBonus_DmgAccu(bonusId) {
			isGain = 1
		}
		dmgBonusState = append(dmgBonusState, &sp.MulCombatDmgAccuBonusState{
			BonusId: bonusId, // 累计奖励Id
			IsGain:  isGain,  // 是否领取奖励
		})
	}

	res = &sp.BossSlotCumulRewardResponse{
		BonusId:       req.BonusId,
		DmgBonusState: dmgBonusState, // 累计伤害奖励列表信息
		Res:           lib.FormatGoodsInfoSps(resGoods),
		BoxRes:        lib.FormatBoxResSps(boxResList),
	}

	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	return
}

// 8685 Boss老虎机 战斗数据刷新
func (p *Player) BossSlotFightReflashRequest(req *sp.BossSlotFightReflashRequest) (res *sp.BossSlotFightReflashResponse) {
	us := p.User

	group, ok := us.GetMCGroup()
	if !ok {
		fmt.Println("查找分组失败")
		return
	}
	gamer, ok := us.GetMCGamer()
	if !ok {
		fmt.Println("查找玩家失败")
		return
	}

	card := us.GetBSGame()
	// 没有卡片怪物信息
	if card == nil {
		fmt.Println("获取卡片怪物信息失败")
		return
	}

	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		fmt.Println("读取配表失败")
		return
	}
	// 活动ID
	activId := int64(wActconfig.ActivID)
	// 查找当前正在被攻击的怪
	var monsterID int64 = 0  // 当前怪
	var fmonsterID int64 = 0 // 最后怪
	for _, item := range wActconfig.BossLst {
		fmonsterID = int64(item)
		boss, _ := group.MBoss[fmonsterID]
		if boss.Hp > 0 {
			monsterID = fmonsterID
			break
		}
	}
	if monsterID == 0 {
		fmt.Println("boss打完，或者没有该Boss")
		monsterID = fmonsterID
	}

	bossLst := make([]*sp.MulCombatBossState, 0)
	for _, item := range wActconfig.BossLst {
		bossTid := int64(item)
		var isGain int64 = 0
		if card.IsGainBonus_BossDefeat(bossTid) {
			isGain = 1
		}
		boss, _ := group.MBoss[int64(item)]
		var isAlive int64 = 0
		if boss.Hp <= 0 {
			isAlive = 1
		}
		// 伤害小于1万，不能领取该奖励。
		if gamer.MEachBossHurt[bossTid] < data.BossHurtReward {
			isGain = 1
		}

		bossLst = append(bossLst, &sp.MulCombatBossState{
			MonsterID: bossTid,
			IsAlive:   isAlive, //0-存活 1-击败
			IsGain:    isGain,  //0-未领取奖励 1-已领取奖励
		})
	}
	// 当前怪-真实血量
	monsterRealHp := group.MBoss[monsterID].Hp

	// 获取前两名
	lgamer, ok := group.GetMCGamerTop(4)
	if !ok {
		fmt.Println("获取前两名信息失败")
		return
	}

	res = &sp.BossSlotFightReflashResponse{
		MonsterID:       monsterID,
		Status:          0,
		BossLst:         bossLst,                          // BOSS列表信息
		MonsterHp:       monsterRealHp,                    // 怪物真实血量
		ShowPlayerlist:  lib.FormatActRankBossLst(lgamer), // 实时排名更新--按需求显示1-2名
		DmgAccu:         gamer.Hurt,                       // 玩家的累计伤害
		ActivID:         activId,                          // 活动ID
		EachBossDmgAccu: lib.FormatBaseKVLst(gamer.MEachBossHurt),
	}
	return
}

// 8686 Boss老虎机 排名
func (p *Player) BossSlotRankRequest(req *sp.BossSlotRankRequest) (res *sp.BossSlotRankResponse) {
	us := p.User

	group, ok := us.GetMCGroup()
	if !ok {
		err := errors.NewErrcode(data.Errcode.NotFound, "获取分组信息失败")
		res = &sp.BossSlotRankResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}
	// 加载Boss，获取配置表信息
	wActconfig, _, err := lib.GetCurrentMulCombatConfig()
	if err != nil {
		log.WithFields(log.Fields{
			"method": "MulCombatBossDefeatRewardRequest",
		}).Error("没找找到活动排名配置表")
		return
	}
	lgamer, ok := group.GetMCGamerAll()
	if !ok {
		err := errors.NewErrcode(data.Errcode.NotFound, "获取排名信息失败")
		res = &sp.BossSlotRankResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	res = &sp.BossSlotRankResponse{
		RankRewardId: int64(wActconfig.RankRewardId),   //排名奖励配置ID
		List:         lib.FormatActRankBossLst(lgamer), //排名列表
	}
	return
}

// 8687 Boss老虎机 玩家复活
func (p *Player) BossSlotResurrectionRequest(req *sp.BossSlotResurrectionRequest) (res *sp.BossSlotResurrectionResponse) {
	us := p.User
	cardGame := us.GetBSGame()

	uProp, err := lib.BloodReturn("BossSlotResurrectionRequest", us, cardGame)
	if err != nil {
		res = &sp.BossSlotResurrectionResponse{
			Errcode: errors.ErrCode(err),
		}
		return
	}

	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})

	res = &sp.BossSlotResurrectionResponse{
		Hp: cardGame.HP,
	}
	return
}
